/// 
/// MaDAson - Toolkit for Model Driven Software Development
/// 
/// Copyright [2006] Marcus Lankenau
/// 
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///  
///     http://www.apache.org/licenses/LICENSE-2.0
///  
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// 

using System;
using System.Collections;
using System.Xml.Serialization;
using System.Text;
using Madason.MetaModel.Validation;

namespace Madason.MetaModel
{
	public class ModelElement
	{
		private TaggedValueList taggedValues;
		private string documentation;
		private string stereotypeName;
		private string name;
		private string id;
		private DependencyList dependencies = new DependencyList();
		private DependencyList dependenciesToMe = new DependencyList();




		/// <summary>
		/// Name of Class
		/// </summary>
		[XmlAttribute("name")]
		public string Name
		{
			get { return name; }
			set { name = value; }
		}

		/// <summary>
		/// get the name in form of camel case (e.g. thisIsMyName)
		/// </summary>
		public string NameCamelCase
		{
			get
			{
				return Name.Substring(0, 1).ToLower() + Name.Substring(1);
			}
		}


		/// <summary>
		/// Get the name in form of pascal case (e.g. ThisIsMyName)
		/// </summary>
		public string NamePascalCase
		{
			get
			{
				return Name.Substring(0, 1).ToUpper() + Name.Substring(1);
			}
		}
		
		
		
		/// <summary>
		/// ID of class
		/// </summary>
		[XmlAttribute("id")]
		public string Id
		{
			get { return id; }
			set { id = value; }
		}

		/// <summary>
		/// List of tagged values
		/// </summary>
		[XmlElement(typeof(TaggedValue), ElementName = "taggedValue")]
		public TaggedValueList TaggedValues
		{
			get 
			{
				if (taggedValues == null) taggedValues = new TaggedValueList();
				return taggedValues;
			}
			set { taggedValues = value;}
		}

		/// <summary>
		/// Documentation for the model element
		/// </summary>
		[XmlElement("documentation")]
		public virtual string Documentation
		{
			get { return documentation == null ? "" : documentation; }
			set { documentation = value; }
		}

		/// <summary>
		/// List of Dependencies this model-element has
		/// </summary>
		public DependencyList Dependencies
		{
			get { return dependencies; }
			set { dependencies = value; }
		}

		/// <summary>
		/// List of Dependencies to this element (passive deps)
		/// </summary>
		public DependencyList DependenciesToMe
		{
			get { return dependenciesToMe; }
			set { dependenciesToMe = value; }
		}

		/// <summary>
		/// find a tagged value
		/// </summary>
		/// <param name="key"></param>
		/// <returns>the value of the tagged value</returns>
		public string FindValue(string key)
		{
			if (TaggedValues == null) return "";

			foreach (TaggedValue tv in TaggedValues)
				if (tv.Key.ToLower() == key.ToLower() && tv.Value != null) return tv.Value;
			return "";
		}


		/// <summary>
		/// check if a tagged value is specified
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public bool HasValue(string key)
		{
			return FindValue(key).Length > 0;
		}

		/// <summary>
		/// StereotypeName
		/// </summary>
		[XmlAttribute("stereoType")]
		public string StereotypeName
		{
			get { return stereotypeName; }
			set { stereotypeName = value; }
		}

		/// <summary>
		/// Stereotype
		/// </summary>
		public Stereotype Stereotype
		{
			get
			{
				if (StereotypeName == null) return Stereotype.None;
				if (StereotypeName.ToLower() == "entity") return Stereotype.Entity;
				if (StereotypeName.ToLower() == "service") return Stereotype.Service;
				if (StereotypeName.ToLower() == "boundary") return Stereotype.Boundary;
				if (StereotypeName.ToLower() == "primarykey") return Stereotype.PrimaryKey;
				if (StereotypeName.ToLower() == "version") return Stereotype.Version;
				if (StereotypeName.ToLower() == "transient") return Stereotype.Transient;
				if (StereotypeName.ToLower() == "enum") return Stereotype.Enum;
				if (StereotypeName.ToLower() == "finder") return Stereotype.Finder;
				return Stereotype.None;
			}
		}

		/// <summary>
		/// add another tagged value
		/// </summary>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public void AddValue(string key, string value)
		{
			TaggedValue tv = new TaggedValue();
			tv.Key = key;
			tv.Value = value;
			if (TaggedValues == null)
				TaggedValues = new TaggedValueList();
			TaggedValues.Add(tv);
		}


		public virtual void ValidateRecursive(ValidationIssueList issues)
		{
			this.Validate(issues);
		}

		public virtual void Validate(ValidationIssueList issues)
		{
		}
	}
}
